import { CreepRole, RoleDatas } from "@/role/types/role"
import CreepController from "../controller"


class RoleUpgrader {

    /**
     *
     * @param creep
     * @returns
     */
    static loop(creep: Creep) {

        const memoryData: RoleDatas[CreepRole.Upgrader] = creep.memory.data as RoleDatas[CreepRole.Upgrader]

        if (!memoryData) {
            creep.log('memory error')
            return
        }

        if (creep.ticksToLive < 50 && creep.store[RESOURCE_ENERGY] > 0) {
            const storage = CreepController.findStorage(creep)
            if (storage) {
                const status = creep.transfer(storage, RESOURCE_ENERGY)
                if (status == ERR_NOT_IN_RANGE) {
                    creep.goTo(storage.pos)
                }
            }
            return
        }

        if (creep.memory.boosting) {
            return
        }
        // boost
        if (creep.room[STRUCTURE_LAB]) {
            if (!creep.memory.boosted) {
                const lab = CreepController.findLab(creep)
                if (lab) {
                    if (!creep.pos.isNearTo(lab.pos)) {
                        creep.goTo(lab.pos)
                        return
                    }
                    else {
                        const status = lab.boostCreep(creep)
                        creep.memory.boosting = true
                        if (status == OK) {
                            delete creep.memory.boosting
                            creep.memory.boosted = true
                        }
                        else {
                            console.log('[boosting]', status)
                        }
                        return
                    }
                }
            }
        }

        // 优先 upgrader
        if (creep.store[RESOURCE_ENERGY] == 0) {

            if (!creep.memory.targetId) {
                if (creep.room.memory.upgradeLinkId) {
                    const link = Game.getObjectById(creep.room.memory.upgradeLinkId) as StructureLink
                    if (link && link.store[RESOURCE_ENERGY] > 0) {
                        creep.memory.targetId = link.id
                    }
                    else {
                        const storeObj = creep.pos.findClosestByPath(FIND_STRUCTURES, {
                            filter: (s) => (
                                s.structureType == STRUCTURE_CONTAINER ||
                                s.structureType == STRUCTURE_STORAGE
                            ) && s.store[RESOURCE_ENERGY] > 100
                        }) as StructureWithStore
                        if (storeObj) {
                            creep.memory.targetId = storeObj.id
                        }
                        // const container = CreepController.findContainer(creep)
                        // if (container && container.store[RESOURCE_ENERGY] > 0) {
                        // creep.memory.targetId = container.id
                        // }
                    }
                }
                else {
                    const storeObj = creep.pos.findClosestByPath(FIND_STRUCTURES, {
                        filter: (s) => (
                            s.structureType == STRUCTURE_CONTAINER ||
                            s.structureType == STRUCTURE_STORAGE
                        ) && s.store[RESOURCE_ENERGY] > 100
                    }) as StructureWithStore
                    if (storeObj) {
                        creep.memory.targetId = storeObj.id
                    }
                    // const container = CreepController.findContainer(creep)
                    // if (container && container.store[RESOURCE_ENERGY] > 0) {
                    // creep.memory.targetId = container.id
                    // }
                }
            }

            if (creep.memory.targetId) {
                const storeObj = Game.getObjectById(creep.memory.targetId) as StructureWithStore
                if (storeObj) {
                    const status = creep.withdraw(storeObj, RESOURCE_ENERGY)
                    if (status == ERR_NOT_IN_RANGE) {
                        creep.goTo(storeObj.pos)
                    }
                    else if (status == ERR_NOT_ENOUGH_ENERGY || status == OK) {
                        delete creep.memory.targetId
                    }
                    return
                }

                creep.say('need Energy')
            }
        }
        else {
            const status = creep.upgradeRoom(creep.room.name)
            if (status == ERR_NOT_IN_RANGE) {
                creep.goTo(creep.room.controller.pos)
            }
            if (status != OK && status != ERR_NOT_IN_RANGE) {
                creep.say('U->error')
            }
        }
    }
}

export default RoleUpgrader
